﻿using System;
using System.Collections.Generic;
using System.Text;

namespace System.Reflection
{
    internal delegate void DynamicPropertySetHandler(object obj, object value, object[] index);

    internal delegate object DynamicPropertyGetHandler(object obj, object[] index);

	public class DynamicPropertyInfo : IDynamicPropertyInfo
    {
        Type type;

        PropertyInfo info;

        DynamicPropertySetHandler setHandler = null;

        DynamicPropertyGetHandler getHandler = null;

        public DynamicPropertyInfo(Type type, PropertyInfo info)
        {
            this.type = type;

            this.info = info;
        }

        public object GetValue(object obj, object[] index)
        {
            int key = info.MetadataToken;

            if (this.getHandler != null)
            {
                return this.getHandler(obj, index);
            }

            if (DynamicCacheFactory<DynamicPropertyGetHandler>.Instance.Contains(key))
            {
                this.getHandler = DynamicCacheFactory<DynamicPropertyGetHandler>.Instance.GetValue(key);
            }
            else
            {
                this.getHandler = DynamicMethodFactory.CreateGetHandler(type, info);

                DynamicCacheFactory<DynamicPropertyGetHandler>.Instance.AddValue(key, this.getHandler);
            }

            return this.getHandler(obj, index);
        }

        public void SetValue(object obj, object value, object[] index)
        {
            int key = info.MetadataToken;

            if (this.setHandler != null)
            {
                this.setHandler(obj, value, index);

                return;
            }

            if (DynamicCacheFactory<DynamicPropertySetHandler>.Instance.Contains(key))
            {
                this.setHandler = DynamicCacheFactory<DynamicPropertySetHandler>.Instance.GetValue(key);
            }
            else
            {
                this.setHandler = DynamicMethodFactory.CreateSetHandler(type, info);

                DynamicCacheFactory<DynamicPropertySetHandler>.Instance.AddValue(key, this.setHandler);
            }

            this.setHandler(obj, value, index);
        }
    }
}
